/**
 * ImageViewerWithControlLineSegments.java
 * 
 * @date: 2012-03-12
 * @author: Xiaoyu Guo (MUN# 200982155)
 * This file is part of the course project for COMP 6752, 
 * Application of Computer Graphics. All the file is written
 * by myself.
 */
package mun.cs6752.project.filter.featureWarping;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import visreed.awt.ArrowStyle;
import visreed.awt.GraphicsHelper;

import mun.cs6752.project.filter.featureWarping.FeatureWarpingParameter.LineSegment;
import mun.cs6752.project.ui.ImageCanvas;

/** An enhanced ImageCanvas with viewing and editing the control line segments
 * @author Xiaoyu Guo
 */
public class ImageViewerWithControlLineSegments extends ImageCanvas implements MouseListener, MouseMotionListener {
    private static final long serialVersionUID = -2992439536313184699L;
    
    private List<LineSegment> controlLines;
    private LineSegment activeLine;
    
    private Stroke cachedActiveLineOutterStroke, cachedActiveLineInnerStroke;
    private Stroke cachedLineOutterStroke, cachedLineInnerStroke;
    
    public ImageViewerWithControlLineSegments(){
        super();
        controlLines = new ArrayList<LineSegment>();
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
    }
    
    public ImageViewerWithControlLineSegments(BufferedImage image){
        super(image);
        controlLines = new ArrayList<LineSegment>();
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
    }
    
    public List<LineSegment> getControlLines(){
        return controlLines;
    }
    
    public void setActiveLine(LineSegment value){
        this.activeLine = value;
        this.repaint();
    }

    @Override 
    public void paint(Graphics g){
        super.paint(g);
        
        Graphics2D g2d = (Graphics2D) g;
        
        // paint the other line segments
        for(LineSegment s : this.controlLines){
            if(!s.equals(this.activeLine)){
                paintLineSegment(g2d, s, Color.white, Color.black);
            }
        }
        
        // paint the active line segment so it is on top of all others
        if(this.activeLine != null){
            paintLineSegment(g2d, this.activeLine, Color.red, Color.black);
        }
        
        
        g.drawString("haha", 0, 0);
    }
    
    private void paintLineSegment(Graphics2D g, LineSegment s, Color foreColor, Color backColor){
        int x1 = (int) Math.round(s.getStartPoint().getX());
        int y1 = (int) Math.round(s.getStartPoint().getY());
        int x2 = (int) Math.round(s.getEndPoint().getX());
        int y2 = (int) Math.round(s.getEndPoint().getY());
        
        if(cachedActiveLineOutterStroke == null){
            // initialize all cached strokes
            cachedActiveLineOutterStroke = new BasicStroke(2.5F);
            cachedActiveLineInnerStroke = new BasicStroke(1.5F);
            cachedLineOutterStroke = new BasicStroke(2.0F);
            cachedLineInnerStroke = new BasicStroke(1.0F);
        }
        
        // TODO conversion between image coordinate to screen coordinate
        
        // calculate the angle of arrow
        double theta = 0.0;
        if(y1 == y2){
            if(x1 < x2){
                theta = 0;
            } else {
                theta = Math.PI;
            }
        } else {
            theta = Math.atan2(y2 - y1, x2 - x1);
        }
        
        Point endPoint = new Point(x2, y2);
        
        // decide whether the line is active
        g.setColor(backColor);
        if(s.equals(this.activeLine)){
            g.setStroke(cachedActiveLineOutterStroke);
        } else {
            g.setStroke(cachedLineOutterStroke);
        }
        g.drawLine(x1, y1, x2, y2);
        GraphicsHelper.drawArrow(g, ArrowStyle.DEFAULT, theta, endPoint);
        
        g.setColor(foreColor);
        if(s.equals(this.activeLine)){
            g.setStroke(cachedActiveLineInnerStroke);
        } else {
            g.setStroke(cachedLineInnerStroke);
        }
        g.drawLine(x1, y1, x2, y2);
        GraphicsHelper.drawArrow(g, ArrowStyle.DEFAULT, theta, endPoint);
        
    }

    /* (non-Javadoc)
     * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseDragged(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }

    /* (non-Javadoc)
     * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseMoved(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }

    /* (non-Javadoc)
     * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO select or de-select the active control line 
        
    }

    /* (non-Javadoc)
     * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
     */
    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }

    /* (non-Javadoc)
     * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }

    /* (non-Javadoc)
     * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }

    /* (non-Javadoc)
     * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }
}
